package com.ht.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ht.api.ISysBaseAPI;
import com.ht.entity.*;
import com.ht.modules.system.entity.*;
import com.ht.modules.system.mapper.*;
import com.ht.modules.system.service.ISysUserService;
import com.ht.utils.TranBaseToImgUtil;
import com.ht.utils.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户表 服务实现类
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysPermissionMapper sysPermissionMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysUserDepartMapper sysUserDepartMapper;
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    private SysDepartMapper sysDepartMapper;

    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;

    @Override
    public SysUser getUserByName(String username) {
        return userMapper.getUserByName(username);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserWithRole(SysUser user, String roles) {
        String idCardFrontBase64 = user.getIdCardFront();
        String idCardBackBase64 = user.getIdCardBack();
        if (idCardFrontBase64 != null && !"".equals(idCardFrontBase64)
                && idCardBackBase64 != null && !"".equals(idCardBackBase64)) {
            // 新增的时候读取身份证得到的base64位图片
            try {
                String idCardFront = TranBaseToImgUtil.GenerateImage(idCardFrontBase64, uploadpath);
                user.setIdCardFront(idCardFront);
                String idCardBack = TranBaseToImgUtil.GenerateImage(idCardBackBase64, uploadpath);
                user.setIdCardBack(idCardBack);
            } catch (Exception e) {
                throw new RuntimeException("Base64格式图片转化错误！");
            }
        }
        this.save(user);
        if (oConvertUtils.isNotEmpty(roles)) {
            String[] arr = roles.split(",");
            for (String roleId : arr) {
                SysUserRole userRole = new SysUserRole(user.getId(), roleId);
                sysUserRoleMapper.insert(userRole);
            }
        }
    }

    @Override
    @CacheEvict(value = "loginUser_cacheRules", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void editUserWithRole(SysUser user, String roles) {
        this.updateById(user);
        //先删后加
        sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
        if (oConvertUtils.isNotEmpty(roles)) {
            String[] arr = roles.split(",");
            for (String roleId : arr) {
                SysUserRole userRole = new SysUserRole(user.getId(), roleId);
                sysUserRoleMapper.insert(userRole);
            }
        }
    }

    @Override
    public void editIDCardInfo(SysUser user) {
        String idCardFrontBase64 = user.getIdCardFront();
        String idCardBackBase64 = user.getIdCardBack();
        if (idCardFrontBase64 != null && !"".equals(idCardFrontBase64)
                && idCardBackBase64 != null && !"".equals(idCardBackBase64)) {
            // 编辑的时候读取身份证得到的base64位图片
            try {
                String idCardFront = TranBaseToImgUtil.GenerateImage(idCardFrontBase64, uploadpath);
                user.setIdCardFront(idCardFront);
                String idCardBack = TranBaseToImgUtil.GenerateImage(idCardBackBase64, uploadpath);
                user.setIdCardBack(idCardBack);
            } catch (Exception e) {
                throw new RuntimeException("Base64格式图片转化错误！");
            }
        }
        this.updateById(user);
    }

    @Override
    public List<String> getRole(String username) {
        return sysUserRoleMapper.getRoleByUserName(username);
    }

    /**
     * 通过用户名获取用户角色集合
     *
     * @param username 用户名
     * @return 角色集合
     */
    @Override
    @Cacheable(value = "loginUser_cacheRules", key = "'Roles_'+#username")
    public Set<String> getUserRolesSet(String username) {
        // 查询用户拥有的角色集合
        List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
        log.info("-------通过数据库读取用户拥有的角色Rules------username： " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
        return new HashSet<>(roles);
    }

    /**
     * 通过用户名获取用户权限集合
     *
     * @param username 用户名
     * @return 权限集合
     */
    @Override
    @Cacheable(value = "loginUser_cacheRules", key = "'Permissions_'+#username")
    public Set<String> getUserPermissionsSet(String username) {
        Set<String> permissionSet = new HashSet<>();
        List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
        for (SysPermission po : permissionList) {
//			// TODO URL规则有问题？
//			if (oConvertUtils.isNotEmpty(po.getUrl())) {
//				permissionSet.add(po.getUrl());
//			}
            if (oConvertUtils.isNotEmpty(po.getPerms())) {
                permissionSet.add(po.getPerms());
            }
        }
        log.info("-------通过数据库读取用户拥有的权限Perms------username： "
                + username + ",Perms size: " + (permissionSet == null ? 0 : permissionSet.size()));
        return permissionSet;
    }

    @Override
    public SysUserCacheInfo getCacheUser(String username) {
        SysUserCacheInfo info = new SysUserCacheInfo();
        info.setOneDepart(true);
//		SysUser user = userMapper.getUserByName(username);
//		info.setSysUserCode(user.getUsername());
//		info.setSysUserName(user.getRealname());


        LoginUser user = sysBaseAPI.getUserByName(username);
        if (user != null) {
            info.setSysUserCode(user.getUsername());
            info.setSysUserName(user.getRealname());
            info.setSysOrgCode(user.getOrgCode());
        }

        //多部门支持in查询
        List<SysDepart> list = sysDepartMapper.queryUserDeparts(user.getId());
        List<String> sysMultiOrgCode = new ArrayList<String>();
        if (list == null || list.size() == 0) {
            //当前用户无部门
            //sysMultiOrgCode.add("0");
        } else if (list.size() == 1) {
            sysMultiOrgCode.add(list.get(0).getOrgCode());
        } else {
            info.setOneDepart(false);
            for (SysDepart dpt : list) {
                sysMultiOrgCode.add(dpt.getOrgCode());
            }
        }
        info.setSysMultiOrgCode(sysMultiOrgCode);

        return info;
    }

    // 根据部门Id查询
    @Override
    public Page<SysUserVo> getUserByDepId(Page<SysUserVo> page, String departId, String username) {
        return page.setRecords(userMapper.getUserByDepId(page, departId, username));
    }


    // 根据角色Id查询
    @Override
    public IPage<SysUser> getUserByRoleId(Page<SysUser> page, String roleId, String username) {
        return userMapper.getUserByRoleId(page, roleId, username);
    }


    @Override
    public void updateUserDepart(String username, String orgCode) {
        baseMapper.updateUserDepart(username, orgCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserWithDepart(SysUser user, String selectedParts) {
//		this.save(user);  //保存角色的时候已经添加过一次了
        if (oConvertUtils.isNotEmpty(selectedParts)) {
            String[] arr = selectedParts.split(",");
            for (String deaprtId : arr) {
                SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
                sysUserDepartMapper.insert(userDeaprt);
            }
        }
    }

    @Override
    public Page<SysUserVo> list(Page<SysUserVo> page, SysUserVo userVo, String column, String order) {
        return page.setRecords(userMapper.list(page, userVo, column, order));
    }

    @Override
    public List<SysUserVo> list(SysUserVo userVo, String column, String order) {
        return userMapper.list(userVo, column, order);
    }

    @Override
    public List<SysUserVo> queryUserVoByDepId(String depId, String username, String realname) {
        return userMapper.queryUserVoByDepId(depId, username, realname);
    }

    @Override
    public void updateCidById(String userId, String cid) {
        userMapper.updateCidById(userId, cid);
    }

    @Override
    public SysUserVo queryById(String id) {
        return userMapper.queryById(id);
    }


    @Override
    public String getUsernameByRole(String role) {
        return userMapper.getUsernameByRole(role.split(","));
    }

    @Override
    public List<SysUser> listUserByRoleCode(String roleCode) {
        return userMapper.listUserByRoleCode(roleCode);
    }

    @Override
    public void editAvatar(SysUser user) {
        //只更新头像，其他的不管
        SysUser resultUser = new SysUser();
        resultUser.setId(user.getId());
        resultUser.setAvatar(user.getAvatar());
        this.updateById(resultUser);
    }

    @Override
    public List<Map<String, String>> getUserWithRole() {
        return userMapper.getUserWithRole();
    }

    /**
     * 根据角色编码获取对应员工信息
     *
     * @param roleCode 编码
     * @return 用户信息
     */
    @Override
    public List<SysUser> getUsersByRoleCode(String roleCode) {
        return userMapper.getUsersByRoleCode(roleCode);
    }

    /**
     * 根据角色编码和部门信息获取对应领导信息
     *
     * @param roleCode 编码
     * @return 用户信息
     */
    @Override
    public List<SysUser> getLeaderByRoleCodeAndDepartId(String roleCode, String departId) {
        return userMapper.getLeaderByRoleCodeAndDepartId(roleCode, departId);
    }

    /**
     * 根据用户ID获取对应角色
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    @Override
    public List<String> getRoleCodeByUserId(String userId) {
        return userMapper.getRoleCodeByUserId(userId);
    }
}
